home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Various / DevDisk 65 (1989)(DevWare PD).zip / DevDisk 65 (1989)(DevWare PD).adf / prosuite / hsl.c < prev    next >
C/C++ Source or Header  |  1990-07-11  |  5KB  |  168 lines

  1.  
  2. /* *** hsl.c ****************************************************************
  3.  *
  4.  * ColorWindow Routine  --  HSL Translation Routines
  5.  *     from Book 1 of the Amiga Programmers' Suite by RJ Mical
  6.  *
  7.  * Copyright (C) 1986, 1987, Robert J. Mical
  8.  * All Rights Reserved.
  9.  *
  10.  * Any or all of this code can be used in any program as long as this
  11.  * entire copyright notice is retained, ok?  Thanks.
  12.  *
  13.  * The Amiga Programmer's Suite Book 1 is copyrighted but freely distributable.
  14.  * All copyright notices and all file headers must be retained intact.
  15.  * The Amiga Programmer's Suite Book 1 may be compiled and assembled, and the 
  16.  * resultant object code may be included in any software product.  However, no 
  17.  * portion of the source listings or documentation of the Amiga Programmer's 
  18.  * Suite Book 1 may be distributed or sold for profit or in a for-profit 
  19.  * product without the written authorization of the author, RJ Mical.
  20.  * 
  21.  * HISTORY      NAME            DESCRIPTION
  22.  * -----------  --------------  --------------------------------------------
  23.  * 3 Jan 87     RJ >:-{)*       Clean-up for release      
  24.  * 27 Feb 86    =RJ Mical=      Modified these routines for Zaphod
  25.  * January 86   =RJ=            Modified the originals for Mandelbrot
  26.  * Late 85      =RJ=            Created the color window for Graphicraft
  27.  *
  28.  * *********************************************************************** */
  29.  
  30.  
  31. #include "color.h"
  32.  
  33.  
  34. SHORT HSLToRGB(hue, saturation, luminance)
  35. USHORT hue, saturation, luminance;
  36. /* This actually doesn't do true HSL to RGB conversion, but it works
  37.  * close enough.  Also, this code could be optimized quite a bit, but
  38.  * I've left it spread out like this so that several years from now 
  39.  * I will be able to figure out what the heck is going on.
  40.  */
  41. {
  42.     LONG red, green, blue;
  43.     LONG reddiff, greendiff, bluediff;
  44.     LONG sixth, rising, falling, invertsaturation;
  45.  
  46.     /* We're going to hold one color off, a second at full, and ramp  
  47.      * the third.  This allows us to visit all two-color combinations.
  48.      * By modifying saturation, all three-color combinations can be seen.
  49.      */
  50.     sixth = hue / 0x2AAB;
  51.     rising = (hue - (sixth * 0x2AAB)) * 6;
  52.     falling = 0xFFFF - rising;
  53.  
  54.     switch (sixth)
  55.         {
  56.         case 0:
  57.             red = 0xFFFF;
  58.             green = rising;
  59.             blue = 0;
  60.             break;
  61.         case 1:
  62.             red = falling;
  63.             green = 0xFFFF;
  64.             blue = 0;
  65.             break;
  66.         case 2:
  67.             red = 0;
  68.             green = 0xFFFF;
  69.             blue = rising;
  70.             break;
  71.         case 3:
  72.             red = 0;
  73.             green = falling;
  74.             blue = 0xFFFF;
  75.             break;
  76.         case 4:
  77.             red = rising;
  78.             green = 0;
  79.             blue = 0xFFFF;
  80.             break;
  81.         case 5:
  82.             red = 0xFFFF;
  83.             green = 0;
  84.             blue = falling;
  85.             break;
  86.         }
  87.  
  88.     red = (red * luminance) >> 16;
  89.     green = (green * luminance) >> 16;
  90.     blue = (blue * luminance) >> 16;
  91.  
  92.     /* The closer saturation is to zero, the closer red, green and blue should
  93.      * be to luminance.
  94.      */
  95.     invertsaturation = 0xFFFF - saturation;
  96.     reddiff = luminance - red;
  97.     red = red + ((reddiff * invertsaturation) >> 16);
  98.     greendiff = luminance - green;
  99.     green = green + ((greendiff * invertsaturation) >> 16);
  100.     bluediff = luminance - blue;
  101.     blue = blue + ((bluediff * invertsaturation) >> 16);
  102.  
  103.     red = (red >> 12) & 0xF;
  104.     green = (green >> 12) & 0xF;
  105.     blue = (blue >> 12) & 0xF;
  106.  
  107.     return( (SHORT)((red << 8) | (green << 4) | (blue)) );
  108. }
  109.  
  110.  
  111.  
  112. VOID RGBToHSL(rgb, returnhue, returnsat, returnlum)
  113. USHORT rgb;
  114. USHORT *returnhue, *returnsat, *returnlum;
  115. {
  116.     LONG min, max, hue, saturation, luminance, differential;
  117.     LONG redpart, greenpart, bluepart;
  118.     LONG workred, workgreen, workblue;
  119.  
  120.     workred = ((rgb >> 8) & 0xF) * 0x111;
  121.     workgreen = ((rgb >> 4) & 0xF) * 0x111;
  122.     workblue = (rgb & 0xF) * 0x111;
  123.  
  124.     if (workred < workgreen) min = workred;
  125.     else min = workgreen;
  126.     if (workblue < min) min = workblue;
  127.  
  128.     if (workred > workgreen) max = workred;
  129.     else max = workgreen;
  130.     if (workblue > max) max = workblue;
  131.  
  132.     luminance = max;
  133.     luminance <<= 4;
  134.     differential = max - min;
  135.  
  136.     if (max != 0)
  137.         {
  138.         saturation = (differential << 16) / max;
  139.         if (saturation > 0xFFFF) saturation = 0xFFFF;
  140.         }
  141.     else 
  142.         saturation = 0;
  143.  
  144.     if (saturation == 0)
  145.         hue = 0;
  146.     else
  147.         {
  148.         redpart = (((max - workred) << 16) / differential) >> 4;
  149.         greenpart = (((max - workgreen) << 16) / differential) >> 4;
  150.         bluepart = (((max - workblue) << 16) / differential) >> 4;
  151.  
  152.         if (workred == max) hue = bluepart - greenpart;
  153.         else if (workgreen == max) hue = 0x2000 + redpart - bluepart;
  154.         else if (workblue == max) hue = 0x4000 + greenpart - redpart;
  155.         if (hue < 0) hue += 0x6000;
  156.         hue = (hue * 2667) / 1000;
  157.         }
  158.  
  159.     *returnhue = hue;
  160.     *returnsat = saturation;
  161.     *returnlum = luminance;
  162. }
  163.  
  164.  
  165.  
  166.  
  167.  
  168.